/*!
    \copyright  Copyright (c) 2021 - 2024 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \defgroup   call_control_client Call Control Client
    @{
    \ingroup    profiles
    \brief      Header file for Call control profile client
*/

#ifndef CALL_CONTROL_CLIENT_H_
#define CALL_CONTROL_CLIENT_H_

#ifdef USE_SYNERGY
#include "bt_types.h"
#include "ccp.h"
#include "voice_sources.h"
#include "device.h"

typedef enum
{
    CCP_NOTIFICATION_ID_PROVIDER_NAME,
    CCP_NOTIFICATION_ID_TECHNOLOGY,
    CCP_NOTIFICATION_ID_SIGNAL_STRENGTH,
    CCP_NOTIFICATION_ID_LIST_CURRENT_CALL,
    CCP_NOTIFICATION_ID_FLAGS,
    CCP_NOTIFICATION_ID_INCOMING_CALL_TARGET_BEARER_URI,
    CCP_NOTIFICATION_ID_CALL_STATE,
    CCP_NOTIFICATION_ID_CALL_CONTROL_POINT,
    CCP_NOTIFICATION_ID_TERMINATION_REASON,
    CCP_NOTIFICATION_ID_INCOMING_CALL,
    CCP_NOTIFICATION_ID_CALL_FRIENDLY_NAME,
} ccp_notification_id_t;

typedef enum
{
    CCP_CHARACTERISTICS_ID_PROVIDER_NAME,
    CCP_CHARACTERISTICS_ID_BEARER_UCI,
    CCP_CHARACTERISTICS_ID_BEARER_TECHNOLOGY,
    CCP_CHARACTERISTICS_ID_BEARER_URI_SCHEMES_SUPPORTED_LIST,
    CCP_CHARACTERISTICS_ID_SIGNAL_STRENGTH,
    CCP_CHARACTERISTICS_ID_SIGNAL_STRENGTH_INTERVAL,
    CCP_CHARACTERISTICS_ID_CURRENT_CALLS_LIST,
    CCP_CHARACTERISTICS_ID_CONTENT_CONTROL_ID,
    CCP_CHARACTERISTICS_ID_FEATURE_AND_STATUS_FLAGS,
    CCP_CHARACTERISTICS_ID_INCOMING_CALL_TARGET_BEARER_URI,
    CCP_CHARACTERISTICS_ID_CALL_STATE,
    CCP_CHARACTERISTICS_ID_INCOMING_CALL,
    CCP_CHARACTERISTICS_ID_CALL_FRIENDLY_NAME,
    CCP_CHARACTERISTICS_ID_CCP_OPTIONAL_OPCODES,
    CCP_CHARACTERISTICS_ID_CALL_CONTROL_POINT,
    CCP_CHARACTERISTICS_ID_INVALID,

    CCP_READ_PROVIDER_NAME = CCP_CHARACTERISTICS_ID_PROVIDER_NAME,
    CCP_READ_BEARER_UCI = CCP_CHARACTERISTICS_ID_BEARER_UCI,
    CCP_READ_BEARER_TECHNOLOGY = CCP_CHARACTERISTICS_ID_BEARER_TECHNOLOGY,
    CCP_READ_BEARER_URI_SCHEMES_SUPPORTED_LIST = CCP_CHARACTERISTICS_ID_BEARER_URI_SCHEMES_SUPPORTED_LIST,
    CCP_READ_SIGNAL_STRENGTH = CCP_CHARACTERISTICS_ID_SIGNAL_STRENGTH,
    CCP_READ_SIGNAL_STRENGTH_INTERVAL = CCP_CHARACTERISTICS_ID_SIGNAL_STRENGTH_INTERVAL,
    CCP_READ_CURRENT_CALLS_LIST = CCP_CHARACTERISTICS_ID_CURRENT_CALLS_LIST,
    CCP_READ_CONTENT_CONTROL_ID = CCP_CHARACTERISTICS_ID_CONTENT_CONTROL_ID,
    CCP_READ_FEATURE_AND_STATUS_FLAGS = CCP_CHARACTERISTICS_ID_FEATURE_AND_STATUS_FLAGS,
    CCP_READ_INCOMING_CALL_TARGET_BEARER_URI = CCP_CHARACTERISTICS_ID_INCOMING_CALL_TARGET_BEARER_URI,
    CCP_READ_CALL_STATE = CCP_CHARACTERISTICS_ID_CALL_STATE,
    CCP_READ_INCOMING_CALL = CCP_CHARACTERISTICS_ID_INCOMING_CALL,
    CCP_READ_CALL_FRIENDLY_NAME = CCP_CHARACTERISTICS_ID_CALL_FRIENDLY_NAME,
    CCP_READ_CCP_OPTIONAL_OPCODES = CCP_CHARACTERISTICS_ID_CCP_OPTIONAL_OPCODES
} ccp_characteristics_id_t;

typedef ccp_characteristics_id_t ccp_read_characteristics_id_t;

/*! CCP Call Termination type */
typedef enum
{
    CCP_TERMINATE_ALL_CALLS,
    CCP_HANGUP_ONGOING_CALLS,
    CCP_REJECT_INCOMING_CALL,
    CCP_TERMINATE_HELD_CALLS
} call_terminate_type_t;

/*! \brief Initialise the Call control client component
 */
void CallControlClient_Init(void);

/*! \brief Function to send the GTBS Opcode to the remote device.
    \param[in] cid    GATT Connection id to which the call control opcode to send.
    \param[in] op     GTBS client control opcode to be sent to remote GTBS server.
    \param[in] val    value to be associated with the opcode(not all opcodes will have value).
 */
void CallControlClient_SendCallControlOpcode(gatt_cid_t cid, uint8 op, int32 val);

/*! \brief Terminates the call for the given source
    \param[in] source Voice source
    \param[in] terminate_type \ref call_terminate_type_t
*/
void CallControlClient_TerminateCalls(voice_source_t source, call_terminate_type_t terminate_type);

/*! \brief Function returns voice context based on call state.
    \param[in] source Voice source

    \return Returns \ref voice_source_provider_context_t.
*/
unsigned CallClientControl_GetContext(voice_source_t source);

/*! \brief Function checks if call related activity is idle or not.
    \param[in] source Voice source

    \return Returns TRUE if call is idle.
*/
bool CallClientControl_IsCallContextIdle(voice_source_t source);

/*! \brief Set the call characteristics notifications
    \param[in] cid    GATT Connection id to which the call characteristics to be set.
    \param[in] type   The type of the notification as ccp_notification_id_t
    \param[in] notification_enable - True/False to enable/disable the notifications.

    \return The le voice context
 */
void CallControlClient_SetCallCharacteristicsNotification(gatt_cid_t cid, ccp_notification_id_t type, bool notification_enable);

/*! \brief Read the CCP call characteristics
    \param[in] cid    GATT Connection id to which the call characteristics to read.
    \param[in] type   The type as \ref ccp_characteristics_id_t

    \return TRUE if read is initiated.
 */
bool CallControlClient_ReadCallCharacteristics(gatt_cid_t cid, ccp_characteristics_id_t id);

/*! \brief Read the CCP cached call characteristics data
    \param[in] cid    GATT Connection id to which the call characteristics to read.
    \param[in] type   The type as \ref ccp_characteristics_id_t
    \param[out] pp_data  Encoded allocated data will be returned in this variable. Caller needs to free the memory

    \return 0 if encoding failed, else length of the data.
 */
uint16 CallControlClient_ReadCachedCallCharacteristics(gatt_cid_t cid, ccp_characteristics_id_t id, uint8 **pp_data);


/*! \brief Write the CCP call characteristics
    \param[in] cid    GATT Connection id to which the call characteristics to read.
    \param[in] type   The type as \ref ccp_characteristics_id_t
    \param[in] len    Length of characteristic value
    \param[in] value  Characteristic value

    \return TRUE if write is initiated.
 */
bool CallControlClient_WriteCallCharacteristics(gatt_cid_t cid, ccp_characteristics_id_t id, uint16 len, uint8 *value);

/*! \brief Send unconditional call control point opcode to the remote
    \param[in] cid    GATT Connection id to which the call characteristics to read.
    \param[in] Opcode   The Opcode to send
    \param[in] callid1   The call Id for which the opcode is to be sent.
    \param[in] callid2   The second call Id. This is required only when the opcode is to join the calls, otherwise can be zero.
 */
void CallControlClient_SendCallControlPointOpcode(gatt_cid_t cid, uint8 Opcode, uint8 callid1, uint8 callid2);

/*! \brief Prints all calls info
 */
void CallControlClient_PrintAllCallsInfo(void);

/*! \brief Release any call which is held/waiting
    \param[in] source  voice source upon which the twc action is to be taken
 */
void CallControlClient_TwcReleaseHeldRejectWaiting(voice_source_t source);

/*! \brief Release the active call and accept incoming call
    \param[in] source  voice source upon which the twc action is to be taken
 */
void CallControlClient_TwcReleaseActiveAcceptOther(voice_source_t source);

/*! \brief Hold the active call and accept incoming call
    \param[in] source  voice source upon which the twc action is to be taken
 */
void CallControlClient_TwcHoldActiveAcceptOther(voice_source_t source);

/*! \brief Join all the calls
    \param[in] source  voice source upon which the twc action is to be taken
 */
void CallControlClient_TwcJoinCalls(voice_source_t source);

/*! \brief Check if CCP is connected or not

    \return TRUE if CCP connected else FALSE
 */
bool CallClientControl_IsCcpConnected(void);

/*! \brief Check if the Call control service is available in remote server and the set the service status accordingly.
    \param[in] cid    GATT Connection id on which the service status needs to be set
    \param[in] service_not_found TRUE if we clearly knows the GTBS service/ GTBS client role is not present in the remote server.
                                 FALSE if we want call control client to check whether GTBS service is there or not in
                                 remote server and set the status accordingly.
 */
void CallControlClient_SetServiceStatusForCid(gatt_cid_t cid, bool service_not_found);

/*! \brief Check if the Call control service is available in remote server and is discovered */
#define CallControlClient_ConnectProfile(cid)   (CallControlClient_SetServiceStatusForCid(cid, FALSE))

/*! \brief Get the content control id for call control client
    \param[in] cid    GATT Connection id to which the content control id is to read.

    \return Content control id of the call control client
 */
uint16 CallClientControl_GetContentControlId(gatt_cid_t cid);

/*! \brief Refreshes the Call state list for CCP
    \param[in] source Voice source
*/
void CallControlClient_RefreshCallState(voice_source_t source);

/*! \brief Register the Call control client component with the Device Database Serialiser */
void CallControlClient_RegisterAsPersistentDeviceDataUser(void);

/*! \brief Get the device from voice source
    \param[in] source Voice source

    \return device_t device associated for the voice source
*/
device_t CallControlClient_FindDeviceFromVoiceSource(voice_source_t source);

/*! \brief Initiate a call through CCP using number
    \param[in] source  voice source to which the call needs to be originated.
    \param[in] digits  The number at which the call is to be place. If the number is NULL, Fixed number is used(123).
    \param[in] number_of_digits  The number of digits passed in the number to which the call is to be initiated
*/
void CallControlClient_InitiateCallUsingNumber(voice_source_t source, const char *digits, unsigned number_of_digits);

/*! \brief Check if CCP instance corrosponding to cid
    \param[in] cid GATT Connection id for which instance validity to be checked.

    \return TRUE if valid call control instance is there for cid
 */
bool CallClientControl_IsConnected(gatt_cid_t cid);

/*! \brief Plays Out of Band ringtone(OOB) for the provided source if there is an incoming call, in following case
           a) If the AG doesn't support in band ringtone
           b) If there is another voice source active

    \param[in]source Source for which OOB ringtone is to be played
 */
void CallControlClient_PlayOutOfBandRingtone(voice_source_t source);

#else /* USE_SYNERGY */

#define CallControlClient_Init()
#define CallClientControl_GetContext(source) (context_voice_disconnected)
#define CallControlClient_SendCallControlOpcode(cid, op, val)
#define CallControlClient_SetCallCharacteristicsNotification(cid, type)
#define CallControlClient_PrintAllCallsInfo(cid)(FALSE)
#define CallControlClient_RegisterAsPersistentDeviceDataUser()

#endif /* USE_SYNERGY */

#endif /* CALL_CONTROL_CLIENT_H */

/*! @} */
